package com.atguigu.tingshu.album.service.impl;

import com.atguigu.tingshu.album.config.VodProperties;
import com.atguigu.tingshu.album.service.VodService;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.util.UploadFileUtil;
import com.atguigu.tingshu.vo.album.TrackMediaInfoVo;
import com.qcloud.vod.VodUploadClient;
import com.qcloud.vod.model.VodUploadRequest;
import com.qcloud.vod.model.VodUploadResponse;
import com.tencentcloudapi.common.AbstractModel;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.vod.v20180717.VodClient;
import com.tencentcloudapi.vod.v20180717.models.*;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.Map;


@Slf4j
@Service
public class VodServiceImpl implements VodService {


    @Autowired
    private VodProperties vodProperties;


    /**
     * 获取VOD媒体文件映射
     *
     * 该方法用于上传媒体文件到VOD，并返回文件的访问URL和文件ID
     * 它首先初始化一个VOD上传客户端，然后构建上传请求对象，
     * 设置文件路径和其他参数，最后调用上传方法并将结果返回
     *
     * @param file 要上传的媒体文件，类型为MultipartFile
     * @return 返回一个包含媒体文件ID和媒体URL的Map对象
     */
    @NotNull
    public Map<String, Object> getVodMediaMap(MultipartFile file) {
        // 0.定义局部变量
        String mediaUrl = "";
        String fileId = "";

        // 1、初始化一个上传客户端
        VodUploadClient client = new VodUploadClient(vodProperties.getSecretId(), vodProperties.getSecretKey());

        // 2.构建上传请求对象
        VodUploadRequest request = new VodUploadRequest();
        // 2.1 要上传文件的地址
        String tempPath = UploadFileUtil.uploadTempPath(vodProperties.getTempPath(), file);
        request.setMediaFilePath(tempPath);
        request.setConcurrentUploadNumber(5);// 对大文件起作用。（s3：minio:大文件上传（断点续传 秒传  分片上传 ））
        // 3.调用上传方法
        try {
            VodUploadResponse response = client.upload(vodProperties.getRegion(), request);
            mediaUrl = response.getMediaUrl();
            fileId = response.getFileId();

            log.info("Upload FileId = {}", response.getFileId());
        } catch (Exception e) {
            // 业务方进行异常处理
            log.error("Upload Err", e);
        }

        // 4.构建上传视频在vod的文件标识以及地址
        HashMap<String, Object> map = new HashMap<>();
        map.put("mediaFileId", fileId);
        map.put("mediaUrl", mediaUrl);
        return map;
    }


    /**
     * 获取媒体文件信息
     * 该方法通过调用腾讯云VOD接口获取媒体文件的详细信息，并封装到TrackMediaInfoVo对象中
     * 主要步骤包括：实例化认证对象、创建VodClient对象、发送请求并处理响应
     *
     * @param mediaFileId 媒体文件ID，用于标识特定的媒体文件
     * @return 返回TrackMediaInfoVo对象，包含媒体文件的基本信息和元数据如果获取失败或解析失败，返回null
     */
    @Override
    public TrackMediaInfoVo getMediaInfo(String mediaFileId) {
        try {
            // 1、实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey，此处还需注意密钥对的保密
            Credential cred = new Credential(vodProperties.getSecretId(), vodProperties.getSecretKey());
            // 2、实例化vod的client对象
            VodClient client = new VodClient(cred, vodProperties.getRegion());
            // 3、实例化一个请求对象
            DescribeMediaInfosRequest req = new DescribeMediaInfosRequest();
            // 3.1 给请求对象设置参数
            String[] fileIds1 = {mediaFileId};
            req.setFileIds(fileIds1);
            // 4、得到vod的响应
            DescribeMediaInfosResponse resp = client.DescribeMediaInfos(req);
            // 输出json格式的字符串回包
            System.out.println(AbstractModel.toJsonString(resp));

            // 初始化TrackMediaInfoVo对象以存储媒体信息
            TrackMediaInfoVo trackMediaInfoVo = new TrackMediaInfoVo();
            // 获取媒体信息集合
            MediaInfo[] mediaInfoSet = resp.getMediaInfoSet();

            // 检查媒体信息集合是否非空且至少包含一个元素
            if (mediaInfoSet != null && mediaInfoSet.length > 0) {
                // 获取第一个媒体信息实例
                MediaInfo mediaInfo = mediaInfoSet[0];
                // 分别获取媒体的基本信息和元数据
                MediaBasicInfo basicInfo = mediaInfo.getBasicInfo();
                MediaMetaData metaData = mediaInfo.getMetaData();
                // 获取音频时长并设置到TrackMediaInfoVo对象中
                Float audioDuration = metaData.getAudioDuration();
                trackMediaInfoVo.setSize(metaData.getSize());
                trackMediaInfoVo.setDuration(audioDuration);
                trackMediaInfoVo.setMediaUrl(basicInfo.getMediaUrl());
                trackMediaInfoVo.setType(basicInfo.getType());
            }
            // 返回封装好的TrackMediaInfoVo对象
            return trackMediaInfoVo;

        } catch (TencentCloudSDKException e) {
            // 处理腾讯云SDK异常，记录错误日志
            log.error("获取媒体信息失败：{}", e.getMessage()); // 异常吃掉了
            //throw new GuiguException(201,"获取媒体信息失败");
        }
        // 如果发生异常或无法获取媒体信息，返回null
        return null;
    }

    @Override
    public void removeMedia(String mediaFileId) {
        try {
            // 1、实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey，此处还需注意密钥对的保密
            Credential cred = new Credential(vodProperties.getSecretId(), vodProperties.getSecretKey());
            // 2、实例化vod的client对象
            VodClient client = new VodClient(cred, vodProperties.getRegion());
            // 3、实例化一个请求对象
            DeleteMediaRequest req = new DeleteMediaRequest();
            // 3.1 给请求对象设置参数
            req.setFileId(mediaFileId);
            //返回一个DeleteMediaResponse对象
            DeleteMediaResponse resp = client.DeleteMedia(req);
            System.out.println(AbstractModel.toJsonString(resp));
        } catch (TencentCloudSDKException e) {
            // 处理腾讯云SDK异常，记录错误日志
            log.error("删除媒体信息失败：{}", e.getMessage());
            throw new GuiguException(201, "删除媒体信息失败");
        }
    }


}
